package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.xcService.pojo.tool.HttpTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.*;
import java.util.regex.Pattern;

/*
* 美团周卡
* */
@Slf4j
public class Plugin_ECARD_P017 implements ChannelService {

    @Override
    public ChannelResult QueryBalance(JSONObject apiConfig) {
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }

    /*  channel_key	String	是	DGTSo6RRT+npVTZ2KSbomQ	美团侧分配的渠道ID，线上另外需要申请.
        app_key	string	是	DGTSo6RRT+npVTZ2KSbomQ==	渠道验签用的标识
        sign	string	是	签名
        expire_time	long	是	时间戳，单位 s
        order_id	string	是	6383928341	渠道方订单ID
        唯一, 每个订单号只能使用一次,使用后被核销
        card_key	string	是	vip_31	周卡商品key
        mobile	string	是	13333334322	手机号码
     */
    @Override
    public ChannelResult Submit(JSONObject apiConfig, Map<String, Object> data) {
        try {
            String AccountVal = String.valueOf(data.get("AccountVal"));
            if (Pattern.matches("^1[3456789]\\d{9}$", AccountVal) != true) {
                return  ChannelResult.error("手机号码异常");
            }
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            params.put("channel_key",apiConfig.getString("channelKey"));
            params.put("app_key",apiConfig.getString("appKey"));
            long timestamp = Instant.now().getEpochSecond();
            params.put("expire_time",timestamp);
            params.put("order_id",data.get("ChannelOrderCode"));
            params.put("card_key",data.get("SUPProductId"));
            params.put("mobile",AccountVal);
            String secretKey = apiConfig.getString("secretKey");
            //获取签名
            String sign = generateSignature(params, secretKey);
            params.put("sign",sign);
            //发送预校验请求
            String verifyUrl = apiConfig.getString("verifyUrl");
            String verifyRes = HttpTool.HttpPost2(verifyUrl, params);
            JSONObject parseObject = JSONObject.parseObject(verifyRes);
            String code = parseObject.getString("code");
            String msg = parseObject.getString("msg");
            //当返回code = 1时, 可通过subcode 捕获具体原因
            //当返回code = 0时, 表示校验通过
            String subCode = parseObject.getString("subcode");

            if(code.equals("0")){
                //校验通过-执行提单请求
                String provideUrl = apiConfig.getString("provideUrl");
                String provideRes = HttpTool.HttpPost2(provideUrl, params);
                JSONObject provideObject = JSONObject.parseObject(provideRes);
                String provideCode = provideObject.getString("code");
                String provideMsg = provideObject.getString("msg");
                String provideSubCode = provideObject.getString("subcode");
                if (provideCode.equals("0")){
                    return ChannelResult.success("下单成功");
                }
                /*  10000	网关层调下游接口异常，需要重试（可重试）
                    16001	此order_id已经被核销
                    16002	渠道已售罄
                    16003	省钱周卡发放异常, 需要重试（可重试）
                    16005	用户未绑定手机号码
                    16006	用户被限购
                    16007	用户被风控
                    16008	渠道过期无效(无有效商品)
                    16009	接口验签失败
                    16010	参数错误
                */
                if (provideSubCode.equals("10000") || provideSubCode.equals("16003")){
                    //返回接口异常，重试
                    return ChannelResult.error(provideSubCode+"##"+provideMsg);
                }
                if(provideSubCode.equals("16001")){
                    System.out.println("重复下单:"+provideSubCode+"##"+provideMsg);
                    return ChannelResult.error("重复下单："+provideSubCode+"##"+provideMsg);
                }
                return ChannelResult.FAILED(provideSubCode+"##"+provideMsg);
            }

            /*  10000	网关层调下游接口异常，需要重试
                16001	此order_id已经被核销
                16002	渠道已售罄
                16005	用户未绑定手机号码
                16006	用户被限购
                16007	用户被风控
                16008	渠道过期无效(无有效商品)
                16009	接口验签失败
                16010	参数错误
                16013	用户手机号码未注册美团账号
                16014	校验服务异常，请重试
            */
            if (code.equals("1")) {
                //校验未通过 - subcode 捕获具体原因
                if (subCode.equals("10000") || subCode.equals("16014")) {
                    //网关层调下游接口异常，需要重试
                    return ChannelResult.error(subCode+"##"+msg);
                }
                if (subCode.equals("16001")) {
                    //此order_id已经被核销
                    System.out.println("重复下单:"+subCode+"##"+msg);
                    return ChannelResult.error("重复下单:"+subCode+"##"+msg);
                }
            }
          return ChannelResult.FAILED("下单失败:"+subCode+"##"+msg);

        }catch (Exception e){
            e.printStackTrace();
            log.error("美团周卡订单接口错误：",e);
            return  ChannelResult.error("美团周卡订单接口错误");
        }
    }



    @Override
    public ChannelResult Query(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Query");
        return  ChannelResult.success("success");
    }

    @Override
    public ChannelResult Notify(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");
    }




    public static String generateSignature(Map<String, Object> params, String secretKey) {

        Set<String> keySet = params.keySet();
        List<String> keyList = new ArrayList<>(keySet);
        Collections.sort(keyList);

        // 加密前字符串拼接
        StringBuilder signStr = new StringBuilder();
        for (String key : keyList) {
            if (key.equals("sign")) {
                continue;
            }

            Object value = params.get(key);
            if (value == null || (value.getClass().isArray()
                    && byte.class.isAssignableFrom(value.getClass().getComponentType()))) {
                continue;
            }

            String valueString = value.toString();

            if (StringUtils.isEmpty(valueString)) {
                continue;
            }
            signStr.append(key).append(value);
        }
        signStr.append("secret").append(secretKey);
        System.out.println("原始字符串组成"+signStr.toString());

        return sha1(signStr.toString());
    }


    private static String sha1(String input) {
        try {
            MessageDigest digest = MessageDigest
                    .getInstance("SHA-1");
            digest.update(input.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

}
